package br.com.foxinline.manager.criar;

import br.com.foxinline.enums.RendaFamiliar;
import br.com.foxinline.modelo.Bairro;
import br.com.foxinline.modelo.Coordenada;
import br.com.foxinline.modelo.Imovel;
import br.com.foxinline.modelo.Proprietario;
import br.com.foxinline.servico.BairroServico;
import br.com.foxinline.servico.DneServico;
import br.com.foxinline.servico.ImovelServico;
import br.com.foxinline.servico.PrefeituraServico;
import br.com.foxinline.servico.ProprietarioServico;
import br.com.foxinline.util.Conexao;
import br.com.foxinline.util.Msg;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.event.map.OverlaySelectEvent;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.PieChartModel;
import org.primefaces.model.map.DefaultMapModel;
import org.primefaces.model.map.LatLng;
import org.primefaces.model.map.Marker;
import org.primefaces.model.map.Polygon;

/**
 *
 * @author roniere
 */
@ViewScoped
@ManagedBean
public class ManagerMapaBairro implements Serializable {

    @EJB
    ImovelServico imovelServico;
    @EJB
    ProprietarioServico proprietarioService;
    @EJB
    DneServico dneService;
    @EJB
    BairroServico bairroServico;
    @EJB
    PrefeituraServico prefeituraServico;
    private DefaultMapModel mapModel;
    private Imovel imovel;
    private List<Imovel> imoveis;
    private Marker marker;
    private Integer zoomLevelMapa;
    private String centroMapa;
    private PieChartModel pieModel;
    private CartesianChartModel categoryModel;
    private Double qtdPessoas;
    private RendaFamiliar rendaFamiliar;
    private Integer qtdBolsaFamilia;
    private Long qtdImoveisBairro;
    private Bairro bairro;
    private boolean connect;

    @PostConstruct
    public void init() {
        this.imovel = new Imovel();
        this.bairro = new Bairro();

        this.centroMapa = prefeituraServico.getCentroMapa();
        this.zoomLevelMapa = prefeituraServico.getZoomMapa();

        this.pieModel = new PieChartModel();
        fillPieModel(0, 0, 0, 0, 0);

        if (prefeituraServico.find().getDesabilitarMapas()) {

            this.connect = false;
        } else if (!Conexao.isInternetReachable()) {

            this.connect = false;
            Msg.messagemWarn("Não foi possível estabelecer uma conexão com a Internet.");
        } else {
            this.connect = true;
            plotar();
        }
    }

    public void plotar() {
        this.mapModel = new DefaultMapModel();
        Polygon polygon = new Polygon();

        List<String> cores = new ArrayList<String>(Arrays.asList(
                "#ff00ff",
                "#00f233",
                "#cc4400",
                "#335600",
                "#99ff11",
                "#ffff00",
                "#ff2299",
                "#dd3366",
                "#aa4433",
                "#223300",
                "#336600",
                "#449900",
                "#55cc00",
                "#66ff00",
                "#ff056c",
                "#662200",
                "#0f4400",
                "#00f916"));

        int index = 0;
        Double lat, lng;
        LatLng coord;

        for (Bairro b : bairroServico.findAll()) {
            List<Coordenada> coordenadas = bairroServico.lstCoordenadaBairro(b);

            if (coordenadas != null && !coordenadas.isEmpty()) {
                lat = 0.0;
                lng = 0.0;

                for (Coordenada coordenada : coordenadas) {

                    LatLng coord1 = new LatLng(coordenada.getLat(), coordenada.getLog());
                    polygon.getPaths().add(coord1);

                    lat += coordenada.getLat();
                    lng += coordenada.getLog();
                }

                polygon.setData(b);
                polygon.setStrokeColor("#000000");
                polygon.setFillColor(cores.get(index++));
                polygon.setStrokeOpacity(1);
                polygon.setFillOpacity(0.3);

                this.mapModel.addOverlay(polygon);

                coord = new LatLng(lat / coordenadas.size(), lng / coordenadas.size());

                Marker mk = new Marker(coord, "Bairro " + b.getNome(), b);

                mk.setDraggable(false);
                this.mapModel.addOverlay(mk);

                polygon = new Polygon();
            }
        }
    }

    public void onPolygonSelect(OverlaySelectEvent event) {

        this.bairro = (Bairro) event.getOverlay().getData();

        this.qtdImoveisBairro = imovelServico.diagQtdImovelPorBairro(this.bairro.getNome());
        this.imoveis = imovelServico.pesquisarImoveisPorBairro(this.bairro);

        this.qtdPessoas = 0.0;
        this.qtdBolsaFamilia = 0;

        this.rendaFamiliar = null;

        Integer municipio = 0;
        Integer estado = 0;
        Integer uniao = 0;
        Integer particular = 0;
        Integer religioso = 0;

        this.pieModel = new PieChartModel();

        for (String str : dneService.getAllBairro()) {
            this.pieModel.set(str, imovelServico.diagQtdImovelPorBairro(str));
        }

        for (Imovel i : this.imoveis) {

            for (Proprietario proprietario : i.getProprietarios()) {
                if (proprietario.getComposicaoFamiliar() != null) {
                    switch (proprietario.getComposicaoFamiliar().getValor()) {
                        case 1:
                            this.qtdPessoas += 1.5;
                            break;
                        case 2:
                            this.qtdPessoas += 4;
                            break;
                        case 3:
                            this.qtdPessoas += 7.5;
                            break;
                        case 4:
                            this.qtdPessoas += 12.5;
                            break;
                        case 5:
                            this.qtdPessoas += 16;
                            break;
                    }
                }

                if (proprietario.getBolsaFamilia() != null && proprietario.getBolsaFamilia()) {
                    this.qtdBolsaFamilia++;
                }

                if (this.rendaFamiliar == null && proprietario.getRendaFamiliar() != null) {
                    this.rendaFamiliar = proprietario.getRendaFamiliar();
                } else if (i.getRendaFamiliar() != null && proprietario.getRendaFamiliar().getValor() > this.rendaFamiliar.getValor()) {
                    this.rendaFamiliar = proprietario.getRendaFamiliar();
                }
            }

            if (i.getPatrimonio() != null) {
                switch (i.getPatrimonio().getValor()) {
                    case 1:
                        municipio++;
                        break;
                    case 2:
                        estado++;
                        break;
                    case 3:
                        uniao++;
                        break;
                    case 4:
                        particular++;
                        break;
                    case 5:
                        religioso++;
                        break;
                }
            }
        }

        this.pieModel = new PieChartModel();
        fillPieModel(municipio, estado, uniao, particular, religioso);
    }

    private void fillPieModel(Integer municipio, Integer estado, Integer uniao, Integer particular, Integer religioso) {
        this.pieModel.set("Município", municipio);
        this.pieModel.set("Estado", estado);
        this.pieModel.set("União", uniao);
        this.pieModel.set("Particular", particular);
        this.pieModel.set("Religioso", religioso);
    }

    public CartesianChartModel getCategoryModel() {
        return categoryModel;
    }

    public void setCategoryModel(CartesianChartModel categoryModel) {
        this.categoryModel = categoryModel;
    }

    public String getCentroMapa() {
        return centroMapa;
    }

    public void setCentroMapa(String centroMapa) {
        this.centroMapa = centroMapa;
    }

    public List<Imovel> getImoveis() {
        return imoveis;
    }

    public void setImoveis(List<Imovel> imoveis) {
        this.imoveis = imoveis;
    }

    public Imovel getImovel() {
        return imovel;
    }

    public void setImovel(Imovel imovel) {
        this.imovel = imovel;
    }

    public DefaultMapModel getMapModel() {
        return mapModel;
    }

    public void setMapModel(DefaultMapModel mapModel) {
        this.mapModel = mapModel;
    }

    public Marker getMarker() {
        return marker;
    }

    public void setMarker(Marker marker) {
        this.marker = marker;
    }

    public PieChartModel getPieModel() {
        return pieModel;
    }

    public void setPieModel(PieChartModel pieModel) {
        this.pieModel = pieModel;
    }

    public Integer getQtdBolsaFamilia() {
        return qtdBolsaFamilia;
    }

    public void setQtdBolsaFamilia(Integer qtdBolsaFamilia) {
        this.qtdBolsaFamilia = qtdBolsaFamilia;
    }

    public Long getQtdImoveisBairro() {
        return qtdImoveisBairro;
    }

    public void setQtdImoveisBairro(Long qtdImoveisBairro) {
        this.qtdImoveisBairro = qtdImoveisBairro;
    }

    public Double getQtdPessoas() {
        return qtdPessoas;
    }

    public void setQtdPessoas(Double qtdPessoas) {
        this.qtdPessoas = qtdPessoas;
    }

    public RendaFamiliar getRendaFamiliar() {
        return rendaFamiliar;
    }

    public void setRendaFamiliar(RendaFamiliar rendaFamiliar) {
        this.rendaFamiliar = rendaFamiliar;
    }

    public Bairro getBairro() {
        return bairro;
    }

    public void setBairro(Bairro bairro) {
        this.bairro = bairro;
    }

    public Integer getZoomLevelMapa() {
        return zoomLevelMapa;
    }

    public void setZoomLevelMapa(Integer zoomLevelMapa) {
        this.zoomLevelMapa = zoomLevelMapa;
    }

    public boolean isConnect() {
        return connect;
    }

    public void setConnect(boolean connect) {
        this.connect = connect;
    }
}
